package com.btb.adapter.controller;

import static java.util.stream.Collectors.toList;

import java.math.BigInteger;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import com.btb.adapter.constant.Constants;
import com.btb.adapter.contract.ActFishService;
import com.btb.adapter.contract.ActHeroService;
import com.btb.adapter.mapper.IpWhiteListMapper;
import com.btb.adapter.mapper.OffChainMapper;
import com.btb.adapter.mapper.TaskConfigMapper;
import com.btb.adapter.mapper.TransferRecordMapper;
import com.btb.adapter.mapper.UpChainFishMapper;
import com.btb.adapter.mapper.UpChainHeroMapper;
import com.btb.adapter.model.IpWhiteList;
import com.btb.adapter.model.IpWhiteListExample;
import com.btb.adapter.model.OffChain;
import com.btb.adapter.model.TaskConfig;
import com.btb.adapter.model.TransferRecord;
import com.btb.adapter.model.UpChainFish;
import com.btb.adapter.model.UpChainHero;
import com.btb.adapter.service.NotifyService;
import com.btb.adapter.service.OffChainService;
import com.btb.adapter.service.TaskConfigService;
import com.btb.adapter.service.TransferRecordService;
import com.btb.adapter.service.UpChainBlockService;
import com.btb.adapter.service.WatchTransferService;
import com.btb.adapter.vo.FishDetail;
import com.btb.adapter.vo.HeroDetail;
import com.btb.adapter.vo.OffChainEventEventResponse;
import com.btb.adapter.vo.UpChainEventEventResponse;

@RestController
public class TestController {
	@Autowired
	private IpWhiteListMapper ipWhiteListMapper;
	@Autowired
	private WatchTransferService watchTransferService;
	@Autowired
	private TransferRecordMapper transferRecordMapper;
	@Autowired
	private NotifyService notifyService;
	@Autowired
	private TaskConfigService taskConfigService;
	@Autowired
	private TransferRecordService transferRecordService;
	@Autowired
	private UpChainFishMapper upChainFishMapper;
	@Autowired
	private UpChainHeroMapper upChainHeroMapper;
	@Autowired
	private OffChainMapper offChainMapper;
	@Autowired
	private UpChainBlockService upChainBlockService;
	@Autowired
	private ActFishService actFishService;
	@Autowired
	private ActHeroService actHeroService;
	@Autowired
	private OffChainService offChainService;

	@GetMapping("/list")
	public List<IpWhiteList> list() {
		return ipWhiteListMapper.selectByExample(new IpWhiteListExample());
	}

	@GetMapping("/insert")
	public String insert() {
		watchTransferService.event("12040589");
		return "success";
	}

	@GetMapping("/payConfirm")
	public String payConfirm() {
		final TaskConfig taskConfig = taskConfigService.findConfigByTaskNameCache(Constants.CONFIRM_PAY);
		TransferRecord transferRecord = transferRecordMapper.selectByPrimaryKey(25L);
		notifyService.pay(transferRecord, taskConfig);
		return "success";
	}

	@GetMapping("/payQuery")
	public List<Long> payQuery() {
		final TaskConfig taskConfig = taskConfigService.findConfigByTaskNameCache(Constants.CONFIRM_PAY);
		List<TransferRecord> queryNotify = transferRecordMapper.queryNotify(taskConfig.getRetryTimes());
		return queryNotify.stream().map(TransferRecord::getId).collect(toList());
	}

	@GetMapping("/upChain/hero/{id}")
	public String upChainFish(@PathVariable("id") Integer id) {
		UpChainHero hero = upChainHeroMapper.selectByPrimaryKey(id);
		upChainBlockService.upChain(hero);
		return "success";
	}

	@GetMapping("/upChain/fish/{id}")
	public String upChainHero(@PathVariable("id") Long id) {
		UpChainFish hero = upChainFishMapper.selectByPrimaryKey(id);
		upChainBlockService.upChain(hero);
		return "success";
	}

	@GetMapping("/upChain/event/hero/{startBlockNumber}/{endBlockNumber}")
	public List<UpChainEventEventResponse> eventHero(@PathVariable("startBlockNumber") String startBlockNumber,
			@PathVariable("endBlockNumber") String endBlockNumber) {
		return actHeroService.upChainEvent(startBlockNumber, endBlockNumber);
	}

	@GetMapping("/upChain/event/fish/{startBlockNumber}/{endBlockNumber}")
	public List<UpChainEventEventResponse> eventFish(@PathVariable("startBlockNumber") String startBlockNumber,
			@PathVariable("endBlockNumber") String endBlockNumber) {
		return actFishService.upChainEvent(startBlockNumber, endBlockNumber);
	}
	
	@GetMapping("/offChain/event/fish/{startBlockNumber}/{endBlockNumber}")
	public List<OffChainEventEventResponse> offChainFishEvent(
			@PathVariable("startBlockNumber") String startBlockNumber,
			@PathVariable("endBlockNumber") String endBlockNumber) {
		return actFishService.offChainEvent(startBlockNumber, endBlockNumber);
	}
	
	@GetMapping("/offChain/event/hero/{startBlockNumber}/{endBlockNumber}")
	public List<OffChainEventEventResponse> offChainHeroEvent(
			@PathVariable("startBlockNumber") String startBlockNumber,
			@PathVariable("endBlockNumber") String endBlockNumber) {
		return actHeroService.offChainEvent(startBlockNumber, endBlockNumber);
	}

	@GetMapping("/detail/fish/{tokenId}")
	public FishDetail detailFish(@PathVariable("tokenId") BigInteger tokenId) {
		return actFishService.fishDetail(tokenId);
	}

	@GetMapping("/detail/hero/{tokenId}")
	public HeroDetail detailHero(@PathVariable("tokenId") BigInteger tokenId) {
		return actHeroService.heroDetail(tokenId);
	}

	@GetMapping("/offChain/{id}")
	public String offChain(@PathVariable("id") Long id) {
		final OffChain offChain = offChainMapper.selectByPrimaryKey(id);
		offChainService.offChain(offChain);
		return "success";
	}

}
